{ config, lib, ... }:
with lib;
let
  cfg = config.roles.server.coturn;
in {
  options.roles.server.coturn = {
    enable = mkOption {
      default = false;
      type = types.bool;
    };
    domain = mkOption {
      default = config.roles.server.domain;
      type = types.str;
    };
    extraConfig = mkOption {
      default = "";
      type = types.str;
    };
    sharedSecretFile = mkOption {
      type = types.str;
    };
  };

  config = mkIf cfg.enable {
    systemd.services.matrix-synapse.preStart = ''
      synapse_coturn=${config.roles.server.synapse.dataDir}/coturn.yaml
      cat << EOF > $synapse_coturn
      turn_shared_secret: $(cat ${cfg.sharedSecretFile})
      EOF
    '';

    networking.firewall = {
      allowedTCPPorts = [ 3487 5349 ];
      allowedUDPPorts = [ 3487 5349 ];
      allowedUDPPortRanges = [
        {
          from = 49152;
          to = 65535;
        }
      ];
    };

    users.users = {
      matrix-synapse.extraGroups = [ "turnserver" ];
      turnserver.extraGroups = [ "acme" ];
    };

    services = {
      coturn = {
        enable = true;
        cert = config.security.acme.certs.${cfg.domain}.directory + "/fullchain.pem";
        inherit (cfg) extraConfig;
        no-tcp-relay = true;
        pkey = config.security.acme.certs.${cfg.domain}.directory + "/key.pem";
        realm = cfg.domain;
        static-auth-secret-file = cfg.sharedSecretFile;
        use-auth-secret = true;
      };

      matrix-synapse = {
        extraConfigFiles = [
          "${config.roles.server.synapse.dataDir}/coturn.yaml"
        ];
        settings.turn_uris = [
          "turn:${cfg.domain}:3487?transport=udp"
          "turn:${cfg.domain}:3487?transport=tcp"
          "turns:${cfg.domain}:5349?transport=udp"
          "turns:${cfg.domain}:5349?transport=tcp"
        ];
      };
    };
  };
}
